/**
  *****************************************************************************
  * @file 
  * @brief 
  * @author luffy
  * @version V1.0.0
  * @date 2022/12/01
  *****************************************************************************
  */
 /* Includes -----------------------------------------------------------------*/
#include "dev_tb67s109.h"
#include "expand_io.h"
/* Private defines ----------------------------------------------------------*/
#define TB67S109_MAX_SPEED   100000   //手册需求速度不可超过100KHz

#define PIN_INIT(pri_pin, pin_name, mode, level)       \
    if (this->pin_name != NULL)                       \
    {                                                  \
        this->private.pri_pin.PIN = this->pin_name;    \
        this->private.pri_pin.MODE = mode;             \
        this->private.pri_pin.INIT_LEVEL = level;      \
        if (Drv_Gpio_Init(&this->private.pri_pin) < 0) \
        {                                              \
            return -1;                                 \
        }                                              \
    }

/* Private Struct -----------------------------------------------------------*/

/* Private enum -------------------------------------------------------------*/

/* Private Variable ---------------------------------------------------------*/
//Pointer

//Array

//Const

/* Private function prototypes ----------------------------------------------*/
static void set_step_dir(dev_tb67s109_t *this, TB67S109_DIR_e dir);
static void set_run_control(dev_tb67s109_t *this, TB67S109_CONTROL_e control);
static int set_step_run(dev_tb67s109_t *this, uint32_t speed, uint32_t pluse);
/***********************************************************************************
  * @brief  设置电机转向
  * ex:
  * @retval 
  * @par 
  * None
  * @par Called functions:
  * None
  **********************************************************************************/
static void set_step_dir(dev_tb67s109_t *this, TB67S109_DIR_e dir)
{
    if (this->PIN_DIR == NULL || this == NULL)
        return;

    switch (dir)
    {
		case TB67S109_POSITIVE:
			this->private.dir.Write(&this->private.dir, 1);
			break;
		case TB67S109_NEGATIVE:
			this->private.dir.Write(&this->private.dir, 0);
			break;
		default:
			break;
    }
}

/***********************************************************************************
  * @brief  设置电机启动停止
  * ex:
  * @retval 
  * @par 
  * None
  * @par Called functions:
  * None
  **********************************************************************************/
static void set_run_control(dev_tb67s109_t *this, TB67S109_CONTROL_e control)
{
    if (this->PIN_EN == NULL || this == NULL)
        return;
    
    switch (control)
    {
		case TB67S109_RUN:
			this->private.enable.Write(&this->private.enable, 0); //High:输出级=’ON’ (正常运行模式)
			this->DELAY_us(1);                                    //手册要求需延时1US
			this->private.mpst.TIMxCmd(&this->private.mpst, 1);
//			Expand_IO_SetState(TCA9535_1,EXPAND_IO_OPEN,0xffff);
//			Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,LED_G1|LED_Y2);
			break;
		case TB67S109_STOP:
			this->private.enable.Write(&this->private.enable, 1);
			this->private.mpst.TIMxCmd(&this->private.mpst, 0);
//		    Expand_IO_SetState(TCA9535_1,EXPAND_IO_OPEN,0xffff);
//			Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,LED_G1);
			break;
		default:
			break;
    }      
}

/***********************************************************************************
  * @brief  设置电机运动参数
  * ex:
  * @retval 
  * @par speed:速度Hz（脉冲数/s）pluse：运动脉冲数
  * None
  * @par Called functions:
  * None
  **********************************************************************************/
static int set_step_run(dev_tb67s109_t *this, uint32_t speed, uint32_t pluse)
{
    if (this == NULL)
        return -1;
    
    if (speed > TB67S109_MAX_SPEED)
        return -1;
    
    this->private.mpst.set_pwm_freq(&this->private.mpst, speed, pluse);
    return 0;
}

/***********************************************************************************
  * @brief  RESET电机
  * ex:
  * @retval 
  * @par
  * None
  * @par Called functions:
  * None
  **********************************************************************************/
static void set_step_reset(dev_tb67s109_t *this, TB67S109_RESET_e reset)
{
    if (this->PIN_RESET == NULL || this == NULL)
        return;

    switch (reset)
    {
		case TB67S109_RESET:
			this->private.reset.Write(&this->private.reset, 1);  //High:将电角设置为初始条件。
			break;
		case TB67S109_SET:
			this->private.reset.Write(&this->private.reset, 1);  //High:将电角设置为初始条件。
		    this->DELAY_us(1000000);
			this->private.reset.Write(&this->private.reset, 0);  //L:正常工作模式
			this->DELAY_us(1000000);
			break;
		default:
			break;
    }
}

/*****************************************************************************
* @brief  初始化
* ex:
* @par
* None
* @retval
*****************************************************************************/
int Dev_Tb67s109_Init(dev_tb67s109_t *this)
{
	// Write Protect
//    PIN_INIT(step,    PIN_STEP,   OUTPUT_DOWN,  HIGHT_LEVEL)
//    PIN_INIT(enable,  PIN_EN,     OUTPUT_DOWN,  HIGHT_LEVEL)
//    PIN_INIT(dir,     PIN_DIR,    OUTPUT_DOWN,  HIGHT_LEVEL)
//    PIN_INIT(reset,   PIN_RESET,  OUTPUT_DOWN,  HIGHT_LEVEL)
//    PIN_INIT(mo,      PIN_MO,     INPUT_UP,     HIGHT_LEVEL)
	
	this->private.step.PIN = this->PIN_STEP;    
	this->private.step.MODE = OUTPUT_UP;             
	this->private.step.INIT_LEVEL = LOW_LEVEL;      
	if (Drv_Gpio_Init(&this->private.step) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->private.enable.PIN = this->PIN_EN;    
	this->private.enable.MODE = OUTPUT_UP;             
	this->private.enable.INIT_LEVEL = LOW_LEVEL;      
	if (Drv_Gpio_Init(&this->private.enable) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->private.dir.PIN = this->PIN_DIR;    
	this->private.dir.MODE = OUTPUT_UP;             
	this->private.dir.INIT_LEVEL = LOW_LEVEL; //HIGHT_LEVEL;      
	if (Drv_Gpio_Init(&this->private.dir) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->private.reset.PIN = this->PIN_RESET;    
	this->private.reset.MODE = OUTPUT_UP;             
	this->private.reset.INIT_LEVEL = HIGHT_LEVEL;      
	if (Drv_Gpio_Init(&this->private.reset) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->private.mo.PIN = this->PIN_MO;    
	this->private.mo.MODE = INPUT_UP;             
	this->private.mo.INIT_LEVEL = HIGHT_LEVEL;      
	if (Drv_Gpio_Init(&this->private.mo) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->DELAY_us(1000000);
	
    this->private.mpst.PWM_DRV = this->PWM_DRV;
    this->private.mpst.TIMER_DRV = this->TIMER_DRV;
    this->private.mpst.PIN_PWM = this->PIN_STEP;
    this->private.mpst.pwm_Prescaler = this->pwm_Prescaler;
    this->private.mpst.pwm_freq	 = this->pwm_freq;
    this->private.mpst.pwm_cmp = 0.5; //50%占空比
    this->private.mpst.pwm_chx = this->pwm_chx;
    this->private.mpst.pwm_clock_freq = this->pwm_clock_freq;
    this->private.mpst.timer_pluse = this->timer_pluse;
    this->private.mpst.PreempPriority = this->PreempPriority;

    this->private.mpst.TIMx_irq_CallBack = this->RunFinish_CallBack;
	
    Drv_Mpwm_Stimer_Init(&this->private.mpst);
	
	// 公共方法赋值
    this->set_step_dir = set_step_dir;
    this->set_run_control = set_run_control;
    this->set_step_run = set_step_run;
	this->set_step_reset = set_step_reset;
	
	set_step_reset(this,TB67S109_SET);  //初始时设置正常工作模式
	
//	this->private.dir.Write(&this->private.dir, 1);
//	this->private.enable.Write(&this->private.enable, 1);
//	
//	// test
//	for(int i=0;i <5000; i++){
//		this->private.step.Write(&this->private.step, 0);
//		this->DELAY_us(100);
//		this->private.step.Write(&this->private.step, 1);
//		this->DELAY_us(100);
//	}
//	
//	this->private.enable.Write(&this->private.enable, 0);
//	this->private.dir.Write(&this->private.dir, 0);
//	
//	this->DELAY_us(2000000);
//	
//	this->private.enable.Write(&this->private.enable, 1);
//	
//		for(int i=0;i <5000; i++){
//		this->private.step.Write(&this->private.step, 0);
//		this->DELAY_us(100);
//		this->private.step.Write(&this->private.step, 1);
//		this->DELAY_us(100);
//	}
//	
	return 0;
}


